package questions;

import org.junit.jupiter.api.Test;

import javax.swing.plaf.TableHeaderUI;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * ArrayList线程不安全
 *   解决办法：
 *      1.Vector.线程安全的集合类 -->方法上加了synchronized，
 *      2.Collections.synchronizedList， --》
 *      3.CopyOnWriteArrayList ReentrantLock+volatile加锁实现同步
 */
public class ArrayListNotThreadSafeDemo {
    public static void main(String[] args) {
        ConcurrentHashMap map =new ConcurrentHashMap(100,0.99F);
    }

    /**
     * @see Vector 利用Vector完成线程安全的数组
     * synchronized关键字修饰了所有操作方法
     */

    @Test
    public void testVector(){
        Vector<String> list =new Vector<>();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString());
                System.out.println(list.size());
            }, String.valueOf(i)).start();
        }
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println(list);
        System.out.println(list.size());

    }
    /**
     * 这个例子，通过{@link CopyOnWriteArrayList }
     * 解决 {@link java.util.ConcurrentModificationException }
     */
    @Test
    public void testCopyOnWriteArrayList() {
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString());
                System.out.println(list.size());
            }, String.valueOf(i)).start();
        }
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println(list);
        System.out.println(list.size());
    }

    /**
     * 这个例子，通过{@link Collections#synchronizedList(java.util.List) }
     * 解决 {@link java.util.ConcurrentModificationException }
     */
    @Test
    public void testCollectionsUtil() {
        List<String> list = Collections.synchronizedList(new ArrayList<>());
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString());
                System.out.println(list.size());
            }, String.valueOf(i)).start();
        }
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println(list);
        System.out.println(list.size());
    }

    /**
     * 这个例子，会发生 {@link java.util.ConcurrentModificationException }
     * 线程过多时，ArrayList会抛出异常
     */
    @Test
    public void testIssue(){
        List<String> list = new ArrayList<>();
        list.forEach(System.out::print);
        for (int i = 0; i <10; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString());
                System.out.println(list);
            },String.valueOf(i)).start();
        }
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
